home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
PROGENV
/
SrcBrowser.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-09
|
14KB
|
597 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "CodeTextView.h" // cpp: max nesting level
#include "SrcBrowser.h"
#include "ET++.h"
#include "StyledText.h"
#include "TextFormatter.h"
#include "OrdColl.h"
#include "WindowSystem.h"
#include "PathLookup.h"
#include "GotoDialog.h"
#include "ClassManager.h"
#include "MenuBar.h"
#include "Env.h"
#include "Data.h"
#include "FindChange_e.h"
#include "Math.h"
#include "Fields.h"
#include "EtProgEnv.h"
#include "ClassList.h"
#include "MethodB.h"
#include "EtPeCmdNo.h"
#include "EtPeManager.h"
#include "EtPeTool.h"
//---- SourceBrowser -----------------------------------------------------------
NewMetaImpl(PeSourceBrowser, Document, (TP(textview), TP(listview), TP(text), TP(ccl), TP(log),
TB(isCCode)));
int PeSourceBrowser::srcCount;
PeSourceBrowser *PeSourceBrowser::browser;
PeSourceBrowser::PeSourceBrowser(Manager *m) : Document(cDocTypeAscii)
{
m->AddManager(this);
Font *fd= gFixedFont;
if (Env::GetValue("CodeText.UseStyles", TRUE))
text= new StyledText(256, fd);
else
text= new GapText(256, fd);
text->SetDefTab(fd->Width(' ') * Env::GetValue("CodeText.TabPos", 8));
ccl= 0;
definition= FALSE;
log= new OrdCollection;
isCCode= FALSE;
base= (srcCount++ == 0);
}
PeSourceBrowser::~PeSourceBrowser()
{
SafeDelete(textview);
SafeDelete(listview);
SafeDelete(text);
SafeDelete(log);
SafeDelete(methods);
SafeDelete(implementors);
}
VObject *PeSourceBrowser::DoMakeContent()
{
textview= new PeSrcBrowserTextView(this, Rectangle(Point(2000,cFit)), text);
listview= new PeClassListView(this);
methods= new PeMethodBrowser(this);
implementors= new PeImplementors(this);
SetFirstHandler(textview);
classScroller= new Scroller(listview, Point(-1, 100));
classScroller->SetFlag(eVObjHFixed);
methodScroller= new Scroller(methods);
implTitle= new TextField(cIdNone, 20, gFixedFont->WithFace(eFaceItalic));
implTitle->SetEditable(FALSE);
return
new VExpander(gPoint2,
new HBox(gPoint2, (VObjAlign)(eVObjHExpand|eVObjVEqual),
classScroller,
methodScroller,
//new VExpander(gPoint2,
new VBox(gPoint2, (VObjAlign)(eVObjVExpand|eVObjHExpand),
implTitle,
new Scroller(implementors),
0
),
0
),
new Scroller(textview, Point(550, 300)),
0
);
}
void PeSourceBrowser::InputKbd(Token &t)
{
if (EtPeTool::WantGrabKeyToken(t, classScroller))
classScroller->Input(t.Pos, t, GetWindow());
else if (EtPeTool::WantGrabKeyToken(t, methodScroller))
methodScroller->Input(t.Pos, t, GetWindow());
else
Document::InputKbd(t);
}
bool PeSourceBrowser::LoadData(Data *d, bool unique)
{
bool ok= Document::LoadData(d, unique);
if (ok) {
ccl= 0;
listview->SelectClass(ccl);
methods->ShowMethodsOf(ccl);
}
return ok;
}
void PeSourceBrowser::SetWindowTitle(char *name)
{
if (base)
GetWindow()->SetTitle(form("*** %s ***", name));
else
Document::SetWindowTitle(name);
}
bool PeSourceBrowser::CanImport(Data *data)
{
if (data)
return data->CanConvert(Meta(Text));
return TRUE;
}
Command *PeSourceBrowser::DoImport(Data *data)
{
Text *t;
if (t= (Text*) data->AsObject(Meta(Text))) {
Command *cmd= textview->InsertText(t);
SafeDelete(t);
return cmd;
}
return gNoChanges;
}
bool PeSourceBrowser::DoWrite(OStream &s, Data*)
{
// ??? terminate last line with a '\n' ???
if ((*text)[text->Size()-1] != '\n')
text->Append('\n');
text->PrintOnAsPureText(s);
return TRUE;
}
bool PeSourceBrowser::DoReadData(Data *data)
{
IStream s(data->GetStreamBuf());
text->ReadFromAsPureText(s, data->SizeHint());
if (isCCode= data->IsCCode())
textview->FormatCode();
else
textview->SetDefaultStyle();
textview->SetText(text);
return TRUE;
}
void PeSourceBrowser::RevealAndSelectLine(int l)
{
LineMark *lm= textview->MarkAtLine(Math::Range(0, textview->Lines()-1, l-1));
textview->SetSelection(lm->Pos(),lm->End());
Rectangle r= textview->SelectionRect();
textview->Scroll(cPartScrollAbs, Point(0,r.origin.y)+Point(0,2));
}
void PeSourceBrowser::Log(Class *cl)
{
if (cl != ccl)
log->Add(cl);
}
void PeSourceBrowser::Control(int id, int what, void *val)
{
PeMethodReference *mr= (PeMethodReference *)val;
switch (what) {
case cPeCLChangedClass:
SetClass((Class*)val, definition);
break;
case cPeChangedMethod:
RevealMethod(mr);
break;
case cPeImplementors:
{
GrShowWaitCursor wc;
implTitle->SetFString(TRUE, "implementors of: %s", mr->Str());
implementors->ShowImplementorsOf(mr, FALSE);
}
break;
case cPeInherited:
implTitle->SetFString(TRUE, "inherited: %s", mr->Str());
implementors->ShowInherited(mr);
break;
case cPeOverrides:
implTitle->SetFString(TRUE, "overrides of: %s", mr->Str());
implementors->ShowImplementorsOf(mr, TRUE);
break;
default:
Document::Control(id, what, val);
}
}
void PeSourceBrowser::SetClass(Class *cl, bool what, bool reveal)
{
Log(cl);
DoSetClass(cl, what, TRUE, reveal);
}
void PeSourceBrowser::RevealMethod(PeMethodReference *mr)
{
SetClass(mr->GetClass(), FALSE, FALSE);
textview->ShowMethod(mr);
methods->SelectMethod(mr);
}
void PeSourceBrowser::DoSetClass(Class *cl, bool decl, bool unique, bool reveal)
{
char fname[1000];
bool sameClass= (cl == ccl && decl == definition);
bool sameFile= FALSE;
if (!sameClass) {
if (!gEtPeManager->FileOfClass(cl, fname, decl)) {
ShowAlert(eAlertNote, "Can't find file @B%s@P in Env::SrcPath\n",
BaseName(fname));
return;
}
FileData *fd= new FileData(fname);
if (fd->UniqueId() != UniqueId()) {
if (! LoadData(fd, unique)) {
listview->SelectClass(ccl);
return;
}
} else {
sameFile= TRUE;
delete fd;
}
definition= decl;
ccl= cl;
listview->SelectClass(ccl);
Send(cPeSourceBrowser, cPeCLSelectClass, ccl);
methods->ShowMethodsOf(cl);
SafeDelete(fd);
}
if (reveal)
SelectSourceLine(sameFile);
}
void PeSourceBrowser::SelectSourceLine(bool)
{
int line;
if (definition)
line= ccl->GetDeclFileLine();
else
line= ccl->GetImplFileLine();
RevealAndSelectLine(line);
}
void PeSourceBrowser::SetMode(bool what)
{
SetClass(ccl, what);
}
void PeSourceBrowser::Spawn()
{
SavedChanges();
Spawn(gEtPeManager, ccl, definition);
}
void PeSourceBrowser::EditSelectedClass()
{
char *classname= FirstWordOfSelection();
Class *clp= gClassManager->Find(classname);
if (clp)
SetClass(clp,definition);
else
ShowAlert(eAlertNote, "No Metaclass found for \"%s\" ?", classname);
}
void PeSourceBrowser::ShowImplementors()
{
PeMethodReference mr(0, 0, FirstWordOfSelection(), FALSE);
implementors->ShowImplementorsOf(&mr, FALSE);
}
void PeSourceBrowser::InspectSomeInstance()
{
Object *op= ccl->SomeMember();
if (!op)
op= ccl->SomeInstance();
if (op)
op->Inspect();
else
ShowAlert(eAlertNote, "No instances found");
}
MenuBar *PeSourceBrowser::DoMakeMenuBar()
{
MenuBar *mb= Document::DoMakeMenuBar();
//---- file menu
Menu *m= new Menu("Classes");
m->AppendItems( "Other", cEDITOTHER,
"Superclass", cEDITSUPER,
"Spawn", cSPAWN,
"-",
"Inspect Some Instance", cINSPECTSOME,
"-",
"Show in Hierarchy", cSHOWHIERARCHY,
"-",
"Previous Class", cGOBACK,
"Empty Classes", cEMPTYCLASSES,
0);
mb->AddMenu(m);
m= new Menu("Methods");
m->AppendItems( "Implementors", cIMPLEMENTORS,
"Overrides", cOVERRIDES,
"Inherited", cINHERITED,
"References", cMETHREFERENCES,
"-",
"Filter...", cFILTER,
"Remove Filter", cREMFILTER,
0);
mb->AddMenu(m);
m= new Menu("Utilities");
m->AppendItems( "Edit Selected Class", cEDITSELECTED,
"Go to Line...", cGOTOLINE,
"Reformat", cREFORMATCODE,
0);
mb->AddMenu(m);
FindChange::InstallChange(mb, textview);
return mb;
}
void PeSourceBrowser::DoSetupMenu(Menu *menu)
{
menu->ToggleItem(cEDITOTHER, definition, "Implementation", "Definition");
if (ccl)
menu->EnableItems(cEDITOTHER,
cSPAWN,
cSHOWHIERARCHY,
cSHOWINHPATH,
cINSPECTSOME,
cUTILMENU,
0);
if (isCCode && text->IsKindOf(StyledText))
menu->EnableItem(cREFORMATCODE);
menu->EnableItems(cGOTOLINE, cEMPTYCLASSES, 0);
if (ccl && ccl->Super())
menu->EnableItem(cEDITSUPER);
if (log->Size() > 1)
menu->EnableItem(cGOBACK);
menu->ToggleItem(cEMPTYCLASSES, listview->HideEmptyClasses(),
"Show All Classes",
"Hide Classes with no Instances");
menu->ReplaceItem(cEDITSELECTED, "Selected Class/Method");
if (!textview->Caret()) {
char *q= FirstWordOfSelection();
if (strlen(q)) {
menu->ReplaceItem(cEDITSELECTED, form("Show \"%s\"", q));
menu->EnableItem(cEDITSELECTED);
}
}
if (methods->GetSelectedMethod() != 0) {
menu->EnableItem(cIMPLEMENTORS);
menu->EnableItem(cOVERRIDES);
menu->EnableItem(cINHERITED);
}
menu->EnableItems(cFILTER, cREMFILTER, 0);
Document::DoSetupMenu(menu);
}
char *PeSourceBrowser::FirstWordOfSelection()
{
static byte buf[60];
textview->SelectionAsString(buf, sizeof buf);
for (byte *q= buf; *q; q++)
if (Isinword(*q)) break;
for (byte *p= q; *p; p++)
if (!Isinword(*p)) break;
*p= '\0';
return (char*) q;
}
Command *PeSourceBrowser::DoMenuCommand(int cmd)
{
char *q;
PeMethodItem *mi= methods->GetSelectedMethod();
switch (cmd) {
case cFIND:
FindChange::ShowChangeDialog(textview);
break;
case cEDITOTHER:
SetMode(!definition);
break;
case cEDITSUPER:
SetClass(ccl->Super(), definition);
break;
case cINSPECTSOME:
InspectSomeInstance();
break;
case cEDITSELECTED:
{
GrShowWaitCursor wc;
q= FirstWordOfSelection();
if (gClassManager->Find(q))
EditSelectedClass();
else
ShowImplementors();
}
break;
case cEMPTYCLASSES:
listview->ToggleHideEmpty();
listview->SelectClass(ccl);
break;
case cGOBACK:
log->RemoveAt(log->Size()-1);
DoSetClass((Class*)log->Last(), definition, TRUE, TRUE);
break;
case cSPAWN:
Spawn();
break;
case cSHOWHIERARCHY:
gEtPeManager->Control(cPeSourceBrowser, cPeShowHierarchy, ccl);
break;
case cGOTOLINE:
GotoLine(textview);
break;
case cREFORMATCODE:
textview->FormatCode();
textview->RepairAll();
return gNoChanges;
case cIMPLEMENTORS:
Control(cPeSourceBrowser, cPeImplementors, mi->mrp);
break;
case cOVERRIDES:
Control(cPeSourceBrowser, cPeOverrides, mi->mrp);
break;
case cINHERITED:
Control(cPeSourceBrowser, cPeInherited, mi->mrp);
break;
case cFILTER:
methods->Filter();
break;
case cREMFILTER:
methods->RemoveFilter();
break;
default:
break;
}
return Document::DoMenuCommand(cmd);
}
void PeSourceBrowser::CollectParts(Collection *col)
{
EvtHandler::CollectParts(col);
}
void PeSourceBrowser::Spawn(Manager *m, Class *cp, bool decl, int at)
{
PeSourceBrowser *sb= new PeSourceBrowser(m);
sb->SetOnDismiss(eMgrClose);
sb->Show();
sb->DoSetClass(cp, decl, FALSE, at == -1);
if (at != -1)
sb->RevealAndSelectLine(at);
}
void PeSourceBrowser::ShowClass(Manager *m, Class *cp, bool decl, int at)
{
if (browser == 0)
browser= new PeSourceBrowser(m);
browser->Show();
browser->SetClass(cp, decl, at == -1);
if (at != -1)
browser->RevealAndSelectLine(at);
}
//---- PeSrcBrowserTextView ------------------------------------------------------
NewMetaImpl0(PeSrcBrowserTextView, CodeTextView);
PeSrcBrowserTextView::PeSrcBrowserTextView(EvtHandler *eh, Rectangle r, Text *t)
: CodeTextView(eh, r, t)
{
}
PrettyPrinter *PeSrcBrowserTextView::MakePrettyPrinter(Text *t,
CharStyle *cs, CharStyle *fs, CharStyle *cds, CharStyle *ps)
{
return new PeSrcBrowserPPrinter(this, t, cs, fs, cds, ps);
}
void PeSrcBrowserTextView::ShowMethod(PeMethodReference *mr)
{
MarkList *mlp= GetMarkList();
Iter next(mlp->MakeIterator());
PeMethodMark *mp;
bool found= FALSE;
while (mp= (PeMethodMark*)next()) {
if (strcmp(mp->className, mr->GetClass()->Name()) == 0 &&
strcmp(mp->method, (char*)mr->Str()) == 0) {
SetSelection(mp->Pos(),mp->End());
found= TRUE;
break;
}
}
// no mark found, use position information stored in mr
if (!found) {
LineMark *lm= MarkAtLine(Math::Range(0, Lines()-1, mr->Line()-1));
SetSelection(lm->Pos(),lm->End());
}
Rectangle r= SelectionRect();
Scroll(cPartScrollAbs, Point(0,r.origin.y)+Point(0,-4));
}
//---- PeSrcBrowserPPrinter ------------------------------------------------------
PeSrcBrowserPPrinter::PeSrcBrowserPPrinter(PeSrcBrowserTextView *tv, Text *t,
CharStyle *cs, CharStyle *fs, CharStyle *cds, CharStyle *ps)
: PrettyPrinter(t, cs, fs, cds, ps)
{
tvp= tv;
tv->GetMarkList()->FreeAll();
}
void PeSrcBrowserPPrinter::Function(int line, int start, int end, char *name, char *classname)
{
PrettyPrinter::Function(line, start, end, name, classname);
if (classname)
tvp->AddMark(new PeMethodMark(classname, name, start, end-start));
}
//---- PeMethodMark --------------------------------------------------------------
NewMetaImpl(PeMethodMark, Mark, (TP(className), TP(method)));
PeMethodMark::PeMethodMark(char *c, char *m, int p, int l) : Mark(p, l)
{
className= strsave(c);
method= strsave(m);
}
PeMethodMark::~PeMethodMark()
{
SafeDelete(className);
SafeDelete(method);
}